home *** CD-ROM | disk | FTP | other *** search
- ;;; Mailing, forwarding, and replying commands for VM
- ;;; Copyright (C) 1989, 1990, 1991 Kyle E. Jones
- ;;;
- ;;; This program is free software; you can redistribute it and/or modify
- ;;; it under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 1, or (at your option)
- ;;; any later version.
- ;;;
- ;;; This program is distributed in the hope that it will be useful,
- ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with this program; if not, write to the Free Software
- ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- (defun vm-do-reply (to-all include-text count)
- (save-restriction
- (widen)
- (let ((mail-buffer (current-buffer))
- (mlist (vm-select-marked-or-prefixed-messages count))
- (dir default-directory)
- (message-pointer vm-message-pointer)
- to cc subject mp in-reply-to references tmp tmp2 newsgroups)
- (setq mp mlist)
- (while mp
- (cond
- ((eq mlist mp)
- (cond ((setq to (vm-get-header-contents (car mp) "Reply-To")))
- ((setq to (vm-get-header-contents (car mp) "From")))
- ((setq to (vm-grok-From_-author (car mp))))
- (t (error "No From: or Reply-To: header in message")))
- (setq subject (vm-get-header-contents (car mp) "Subject")
- in-reply-to (and vm-in-reply-to-format
- (vm-sprintf 'vm-in-reply-to-format (car mp)))
- in-reply-to (and (not (equal "" in-reply-to)) in-reply-to))
- (and subject vm-reply-subject-prefix
- (let ((case-fold-search t))
- (not
- (equal
- (string-match (regexp-quote vm-reply-subject-prefix)
- subject)
- 0)))
- (setq subject (concat vm-reply-subject-prefix subject))))
- (t (cond ((setq tmp (vm-get-header-contents (car mp) "Reply-To"))
- (setq to (concat to "," tmp)))
- ((setq tmp (vm-get-header-contents (car mp) "From"))
- (setq to (concat to "," tmp)))
- ((setq tmp (vm-grok-From_-author (car mp)))
- (setq to (concat to "," tmp)))
- (t (error "No From: or Reply-To: header in message")))))
- (if to-all
- (progn
- (setq tmp (vm-get-header-contents (car mp) "To"))
- (setq tmp2 (vm-get-header-contents (car mp) "Cc"))
- (if tmp
- (if cc
- (setq cc (concat cc "," tmp))
- (setq cc tmp)))
- (if tmp2
- (if cc
- (setq cc (concat cc "," tmp2))
- (setq cc tmp2)))))
- (setq references
- (cons (vm-get-header-contents (car mp) "References")
- (cons (vm-get-header-contents (car mp) "In-reply-to")
- (cons (vm-get-header-contents (car mp) "Message-ID")
- references))))
- (setq newsgroups
- (cons (or (and to-all (vm-get-header-contents (car mp) "Followup-To"))
- (vm-get-header-contents (car mp) "Newsgroups"))
- newsgroups))
- (setq mp (cdr mp)))
- (if vm-strip-reply-headers
- (let ((mail-use-rfc822 t))
- (and to (setq to (mail-strip-quoted-names to)))
- (and cc (setq cc (mail-strip-quoted-names cc)))))
- (setq to (vm-parse-addresses to)
- cc (vm-parse-addresses cc))
- (if vm-reply-ignored-addresses
- (setq to (vm-strip-ignored-addresses to)
- cc (vm-strip-ignored-addresses cc)))
- (setq to (vm-delete-duplicates to))
- (setq cc (vm-delete-duplicates
- (append (vm-delete-duplicates cc)
- to (copy-sequence to))
- t))
- (and to (setq to (mapconcat 'identity to ",\n ")))
- (and cc (setq cc (mapconcat 'identity cc ",\n ")))
- (and (null to) (setq to cc cc nil))
- (setq references (delq nil references)
- references (mapconcat 'identity references " ")
- references (vm-parse references "[^<]*\\(<[^>]+>\\)")
- references (vm-delete-duplicates references)
- references (if references (mapconcat 'identity references "\n\t")))
- (setq newsgroups (delq nil newsgroups)
- newsgroups (mapconcat 'identity newsgroups ",")
- newsgroups (vm-parse newsgroups "[ \t\f\r\n,]*\\([^ \t\f\r\n,]+\\)")
- newsgroups (vm-delete-duplicates newsgroups)
- newsgroups (if newsgroups (mapconcat 'identity newsgroups ",")))
- (vm-mail-internal
- (format "reply to %s%s" (vm-su-full-name (car mlist))
- (if (cdr mlist) ", ..." ""))
- to subject in-reply-to cc references newsgroups)
- (use-local-map (copy-keymap (current-local-map)))
- (local-set-key "\C-c\C-y" 'vm-yank-message)
- (local-set-key "\C-cy" 'vm-yank-message-other-folder)
- (local-set-key "\C-c\C-s" 'vm-mail-send)
- (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
- (local-set-key "\C-c\C-v" vm-mode-map)
- (make-local-variable 'vm-reply-list)
- (setq vm-mail-buffer mail-buffer
- vm-system-state 'replying
- vm-message-pointer message-pointer
- vm-reply-list mlist
- default-directory dir)
- (if include-text
- (save-excursion
- (goto-char (point-min))
- (re-search-forward (concat "^" mail-header-separator "$") nil 0)
- (forward-char 1)
- (while mlist
- (vm-yank-message (car mlist))
- (goto-char (point-max))
- (setq mlist (cdr mlist))))))))
-
- (defun vm-strip-ignored-addresses (addresses)
- (setq addresses (copy-sequence addresses))
- (let (re-list list)
- (setq re-list vm-reply-ignored-addresses)
- (while re-list
- (setq addr-list addresses)
- (while addr-list
- (if (string-match (car re-list) (car addr-list))
- (setq addresses (delq (car addr-list) addresses)))
- (setq addr-list (cdr addr-list)))
- (setq re-list (cdr re-list))))
- addresses )
-
- (defun vm-mail-yank-default (message)
- (save-excursion
- (delete-region (point) (progn (search-forward "\n\n") (point)))
- (if vm-included-text-attribution-format
- (insert (vm-sprintf 'vm-included-text-attribution-format message)))
- (while (and (re-search-forward "^" nil t) (< (point) (mark)))
- (replace-match vm-included-text-prefix t t))))
-
- (defun vm-yank-message-other-folder (folder &optional prefix-argument)
- "Like vm-yank-message except the message is yanked from a folder other
- than the one that spawned the current Mail mode buffer. The name of the
- folder is read from the minibuffer.
-
- Don't call this function from a program."
- (interactive
- (list
- (let ((dir (if vm-folder-directory
- (expand-file-name vm-folder-directory)
- default-directory)))
- (read-file-name "Yank from folder: " dir nil t))
- current-prefix-arg ))
- (let ((b (current-buffer)) newbuf sumbuf)
- (set-buffer (or (get-file-buffer folder) (find-file-noselect folder)))
- (setq newbuf (current-buffer))
- (if (not (eq major-mode 'vm-mode))
- (vm-mode))
- (if (null vm-message-pointer)
- (error "No messages in folder %s" folder))
- (save-excursion
- (save-window-excursion
- (save-window-excursion
- (vm-summarize))
- (switch-to-buffer vm-summary-buffer)
- (setq sumbuf (current-buffer))
- (delete-other-windows)
- (set-buffer b)
- (unwind-protect
- (let ((prefix-arg prefix-argument)
- (vm-mail-buffer newbuf))
- (command-execute 'vm-yank-message))
- (bury-buffer newbuf)
- (bury-buffer sumbuf))))))
-
- (defun vm-yank-message (message &optional prefix)
- "Yank message number N into the current buffer at point.
- When called interactively N is always read from the minibuffer. When
- called non-interactively the first argument is expected to be a message
- struct.
-
- This command is meant to be used in VM created Mail mode buffers; the
- yanked message comes from the mail buffer containing the message you
- are replying to, forwarding, or invoked VM's mail command from.
-
- All message headers are yanked along with the text. Point is left
- before the inserted text, the mark after. Any hook functions bound to
- mail-yank-hooks are run, aftert inserting the text and setting point
- and mark.
-
- Prefix arg means to ignore mail-yank-hooks, don't set the mark, prepend the
- value of vm-included-text-prefix to every yanked line, and don't yank any
- headers other than those specified in vm-visible-headers/vm-invisible-headers."
- (interactive
- (list
- ;; What we really want for the first argument is a message struct,
- ;; but if called interactively, we let the user type in a message
- ;; number instead.
- (let (mp default (result 0) prompt)
- (save-excursion
- (vm-select-folder-buffer)
- (setq default (and vm-message-pointer
- (vm-number-of (car vm-message-pointer)))
- prompt (if default
- (format "Yank message number: (default %s) "
- default)
- "Yank message number: "))
- (while (zerop result)
- (setq result (read-string prompt))
- (and (string= result "") default (setq result default))
- (setq result (string-to-int result)))
- (if (null (setq mp (nthcdr (1- result) vm-message-list)))
- (error "No such message.")))
- (car mp))
- current-prefix-arg ))
- (if (not (bufferp vm-mail-buffer))
- (error "This is not a VM Mail mode buffer."))
- (if (null (buffer-name vm-mail-buffer))
- (error "The mail buffer containing message %d has been killed."
- (vm-number-of message)))
- (let ((b (current-buffer)) (start (point)) mp end)
- (save-restriction
- (widen)
- (save-excursion
- (set-buffer (marker-buffer (vm-start-of message)))
- (save-restriction
- (widen)
- (append-to-buffer b (if prefix
- (vm-vheaders-of message)
- (vm-start-of message))
- (vm-text-end-of message))
- (setq end (vm-marker (+ start (- (vm-text-end-of message)
- (if prefix
- (vm-vheaders-of message)
- (vm-start-of message)))) b))))
- (if prefix
- (save-excursion
- (while (and (< (point) end) (re-search-forward "^" end t))
- (replace-match vm-included-text-prefix t t)
- (forward-line)))
- ;; Delete UNIX From or MMDF ^A^A^A^A line
- (delete-region (point) (progn (forward-line) (point)))
- (push-mark end)
- (if mail-yank-hooks
- (run-hooks 'mail-yank-hooks)
- (vm-mail-yank-default message))))))
-
- (defun vm-mail-send-and-exit (arg)
- "Just like mail-send-and-exit except that VM flags the appropriate message(s)
- as having been replied to, if appropriate."
- (interactive "P")
- (let ((reply-buf (current-buffer)))
- (mail-send-and-exit arg)
- (save-excursion
- (set-buffer reply-buf)
- (cond ((eq vm-system-state 'replying)
- (vm-mark-replied))
- ((eq vm-system-state 'forwarding)
- (vm-mark-forwarded)))
- (vm-rename-current-mail-buffer)
- ;; keep this buffer if the user demands it
- (if (memq (current-buffer) vm-kept-mail-buffers)
- (setq vm-kept-mail-buffers
- (delq (current-buffer) vm-kept-mail-buffers)))
- (setq vm-kept-mail-buffers (cons (current-buffer) vm-kept-mail-buffers))
- (if (not (eq vm-keep-sent-messages t))
- (let ((extras (nthcdr (or vm-keep-sent-messages 0) vm-kept-mail-buffers)))
- (mapcar (function (lambda (b) (and (buffer-name b) (kill-buffer b)))) extras)
- (and vm-kept-mail-buffers extras
- (setcdr (memq (car extras) vm-kept-mail-buffers) nil)))))))
-
- (defun vm-mail-send ()
- "Just like mail-send except that VM flags the appropriate message(s)
- as having been replied to, if appropriate."
- (interactive)
- (mail-send)
- (vm-rename-current-mail-buffer)
- (cond ((eq vm-system-state 'replying)
- (vm-mark-replied))
- ((eq vm-system-state 'forwarding)
- (vm-mark-forwarded))))
-
- (defun vm-rename-current-mail-buffer ()
- (if (not (string-match "^sent " (buffer-name)))
- (let (prefix name n)
- (if (not (= ?* (aref (buffer-name) 0)))
- (setq prefix (format "sent %s" (buffer-name)))
- (let (recipients)
- (cond ((not (zerop (length (setq recipients (mail-fetch-field "To"))))))
- ((not (zerop (length (setq recipients (mail-fetch-field "Cc"))))))
- (t (setq recipient "the horse with no name")))
- (setq prefix (format "sent mail to %s" recipients))))
- (setq name prefix n 1)
- (while (get-buffer name)
- (setq name (format "%s<%d>" prefix n))
- (vm-increment n))
- (rename-buffer name))))
-
- (defun vm-mark-replied ()
- (save-excursion
- (let ((mp vm-reply-list))
- (while mp
- (if (null (marker-buffer (vm-start-of (car mp))))
- ()
- (set-buffer (marker-buffer (vm-start-of (car mp))))
- (cond ((and (memq (car mp) vm-message-list)
- (null (vm-replied-flag (car mp))))
- (vm-set-replied-flag (car mp) t))))
- (setq mp (cdr mp)))
- (vm-update-summary-and-mode-line))))
-
- (defun vm-mark-forwarded ()
- (save-excursion
- (let ((mp vm-forward-list))
- (while mp
- (if (null (marker-buffer (vm-start-of (car mp))))
- ()
- (set-buffer (marker-buffer (vm-start-of (car mp))))
- (cond ((and (memq (car mp) vm-message-list)
- (null (vm-forwarded-flag (car mp))))
- (vm-set-forwarded-flag (car mp) t))))
- (setq mp (cdr mp)))
- (vm-update-summary-and-mode-line))))
-
- (defun vm-reply (count)
- "Reply to the sender of the current message.
- Numeric prefix argument N mans to reply to the current message plus the
- next N-1 messages. A negative N means reply to the current message and
- the previous N-1 messages.
-
- If invoked on marked messages (via vm-next-command-uses-marks),
- all marked messages will be replied to.
-
- You will be placed into a standard Emacs Mail mode buffer to compose and
- send your message. See the documentation for the function `mail' for
- more info.
-
- Note that the normal binding of C-c C-y in the reply buffer is
- automatically changed to vm-yank-message during a reply. This
- allows you to yank any message from the current folder into a
- reply.
-
- Normal VM commands may be accessed in the reply buffer by prefixing them
- with C-c C-v."
- (interactive "p")
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (vm-do-reply nil nil count))
-
- (defun vm-reply-include-text (count)
- "Reply to the sender (only) of the current message and include text
- from the message. See the documentation for function vm-reply for details."
- (interactive "p")
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (vm-do-reply nil t count))
-
- (defun vm-followup (count)
- "Reply to all recipients of the current message.
- See the documentation for the function vm-reply for details."
- (interactive "p")
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (vm-do-reply t nil count))
-
- (defun vm-followup-include-text (count)
- "Reply to all recipients of the current message and include text from
- the message. See the documentation for the function vm-reply for details."
- (interactive "p")
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (vm-do-reply t t count))
-
- (defun vm-forward-message ()
- "Forward the current message to one or more third parties.
- You will be placed in a Mail mode buffer as is usual with replies, but you
- must fill in the To: and Subject: headers manually."
- (interactive)
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (if (eq last-command 'vm-next-command-uses-marks)
- (progn (setq this-command 'vm-next-command-uses-marks)
- (command-execute 'vm-send-digest))
- (let ((b (current-buffer))
- (dir default-directory)
- (mp vm-message-pointer)
- start)
- (save-restriction
- (widen)
- (vm-mail-internal
- (format "forward of %s:%s" (buffer-name)
- (vm-number-of (car vm-message-pointer)))
- nil
- (and vm-forwarding-subject-format
- (vm-sprintf 'vm-forwarding-subject-format
- (car mp))))
- (use-local-map (copy-keymap (current-local-map)))
- (local-set-key "\C-c\C-y" 'vm-yank-message)
- (local-set-key "\C-cy" 'vm-yank-message-other-folder)
- (local-set-key "\C-c\C-s" 'vm-mail-send)
- (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
- (local-set-key "\C-c\C-v" vm-mode-map)
- (make-local-variable 'vm-forward-list)
- (setq vm-mail-buffer b
- vm-system-state 'forwarding
- vm-forward-list (list (car mp))
- vm-message-pointer mp
- default-directory dir)
- (goto-char (point-max))
- (insert "------- Start of forwarded message -------\n")
- (setq start (point))
- (insert-buffer-substring b
- (save-excursion
- (set-buffer b)
- (goto-char (vm-start-of (car mp)))
- (forward-line 1)
- (point))
- (vm-text-end-of (car mp)))
- (if vm-rfc934-forwarding
- (vm-rfc934-char-stuff-region start (point)))
- (insert "------- End of forwarded message -------\n")
- (goto-char (point-min))
- (end-of-line)))))
-
- (defun vm-mail ()
- "Send a mail message from within VM, or from without."
- (interactive)
- (vm-session-initialization)
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (let ((mail-buffer (if (memq major-mode '(vm-mode vm-virtual-mode))
- (current-buffer))))
- (vm-mail-internal)
- (if (null mail-buffer)
- ()
- (use-local-map (copy-keymap (current-local-map)))
- (local-set-key "\C-c\C-y" 'vm-yank-message)
- (local-set-key "\C-c\C-v" vm-mode-map)
- (setq vm-mail-buffer mail-buffer))
- (local-set-key "\C-c\C-s" 'vm-mail-send)
- (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
- (local-set-key "\C-cy" 'vm-yank-message-other-folder)))
-
- (defun vm-resend-bounced-message ()
- "Extract the original text from a bounced message and resend it.
- You will be placed in a Mail mode buffer with the extracted message and
- you can change the recipient address before resending the message."
- (interactive)
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (let ((b (current-buffer)) start
- (dir default-directory)
- (lim (vm-text-end-of (car vm-message-pointer))))
- (save-restriction
- (widen)
- (save-excursion
- (goto-char (vm-text-of (car vm-message-pointer)))
- (let (case-fold-search)
- ;; What a wonderful world it would be if mailers used the
- ;; message encapsulation standard instead the following
- ;; ad hockeries.
- (or
- ;; sendmail
- (search-forward "----- Unsent message follows" lim t)
- ;; smail 2.x
- (search-forward "======= text of message follows" lim t)
- ;; smail 3.x (?)
- (search-forward "- Message text follows:" lim t)
- ;; MMDF
- (search-forward "Your message follows:\n" lim t)
- (search-forward " Your message begins as follows:\n" lim t)
- ;; zmailer (?)
- (search-forward "--- Original Message ---" lim t)
- ;; Grapevine
- (search-forward "The text of your message was\n---" lim t)
- (error "This does not appear to be a bounced message."))
- (forward-line 1)
- (setq start (point))))
- (vm-mail-internal
- (format "retry of %s:%s" (buffer-name)
- (vm-number-of (car vm-message-pointer))))
- (use-local-map (copy-keymap (current-local-map)))
- (local-set-key "\C-c\C-y" 'vm-yank-message)
- (local-set-key "\C-cy" 'vm-yank-message-other-folder)
- (local-set-key "\C-c\C-s" 'vm-mail-send)
- (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
- (local-set-key "\C-c\C-v" vm-mode-map)
- (goto-char (point-min))
- (insert-buffer-substring b start lim)
- (delete-region (point) (point-max))
- (goto-char (point-min))
- ;; some mailers leave grot at the top of the message.
- ;; trim it.
- (while (not (looking-at vm-generic-header-regexp))
- (delete-region (point) (progn (forward-line 1) (point))))
- ;; delete all but pertinent headers
- (while (looking-at vm-generic-header-regexp)
- (let ((match-end-0 (match-end 0)))
- (if (or
- (looking-at "From:\\|To:\\|Cc:\\|Subject:\\|In-Reply-To\\|Resent-")
- (looking-at "Newsgroups\\|References"))
- (goto-char match-end-0)
- (delete-region (point) match-end-0))))
- (insert mail-header-separator)
- (if (= (following-char) ?\n)
- (forward-char 1)
- (insert "\n"))
- (setq vm-mail-buffer b
- default-directory dir))))
-
- (defun vm-resend-message (recipients)
- "Resend the current message to someone else.
- You will be proompted in the minibuffer for the space or comma
- separated recipient list."
- (interactive "sResend message to: ")
- (vm-follow-summary-cursor)
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (let ((vmp vm-message-pointer)
- recipient-list t-buffer m-buffer
- doomed-buffers
- (pop-up-windows (and pop-up-windows (eq vm-mutable-windows t)))
- (mail-header-seaprator ""))
- (setq recipient-list (vm-parse recipients "[ \t,]*\\([^ ,\t]+\\)[ \t,]*"))
- (unwind-protect
- (progn
- (vm-within-current-message-buffer
- (vm-save-restriction
- (widen)
- (save-excursion
- (setq m-buffer (generate-new-buffer "*VM resend*"))
- (set-buffer m-buffer)
- (make-local-variable 'vm-forward-list)
- (setq vm-system-state 'forwarding
- vm-forward-list (list (car vmp)))
- (erase-buffer)
- (insert-buffer-substring
- (marker-buffer (vm-start-of (car vmp)))
- (vm-start-of (car vmp))
- (vm-text-end-of (car vmp))))))
- (set-buffer m-buffer)
- (goto-char (point-min))
- ;; some mailers leave grot at the top of the message.
- ;; trim it.
- (while (not (looking-at vm-generic-header-regexp))
- (delete-region (point) (progn (forward-line 1) (point))))
- ;; indicate that this is a resend. this should be all
- ;; that's needed, as sendmail will generate the rest.
- ;; But generate a Resent-From is the user is picky
- ;; about the From header.
- (if vm-mail-header-from
- (insert "Resent-From: " vm-mail-header-from "\n"))
- (insert "Resent-To: " (mapconcat 'identity recipient-list ", ") "\n")
- ;; delete all but pertinent headers
- (while (looking-at vm-generic-header-regexp)
- (let ((match-end-0 (match-end 0)))
- (if (not (looking-at "X-VM-\\|Status:"))
- (goto-char match-end-0)
- (delete-region (point) match-end-0))))
- (setq t-buffer
- (generate-new-buffer
- (format "transcript of resend to %s" recipients)))
- (goto-char (point-min))
- (message "Sending...")
- (apply 'call-process-region
- (nconc (list (point-min) (point-max)
- sendmail-program
- nil t-buffer mail-interactive
- "-oi" "-oem")
- (if mail-interactive
- (list "-v")
- (list "-odb"))
- recipient-list))
- (vm-mark-forwarded)
- (set-buffer t-buffer)
- (if (zerop (buffer-size))
- (message "Sent.")
- (display-buffer t-buffer)
- (bury-buffer t-buffer)
- (setq t-buffer nil)
- (message "")))
- (and t-buffer (kill-buffer t-buffer))
- (and m-buffer (kill-buffer m-buffer)))))
-
- (defun vm-send-digest (&optional prefix)
- "Send a digest of all messages in the current folder to recipients.
- You will be placed in a *mail* buffer as is usual with replies, but you
- must fill in the To: and Subject: headers manually.
-
- Prefix arg means to insert a list of preamble lines at the beginning of
- the digest. One line is generated for each message being digestified.
- The variable vm-digest-preamble-format determines the format of the
- preamble lines.
-
- If invoked on marked messages (via vm-next-command-uses-marks),
- only marked messages will be put into the digest."
- (interactive "P")
- (vm-select-folder-buffer)
- (vm-check-for-killed-summary)
- (vm-error-if-folder-empty)
- (let ((b (current-buffer))
- (dir default-directory)
- (mp vm-message-pointer)
- ;; prefix arg doesn't have "normal" meaning here, so only call
- ;; vm-select-marked-or-prefixed-messages if we're using marks.
- (mlist (if (eq last-command 'vm-next-command-uses-marks)
- (vm-select-marked-or-prefixed-messages 0)
- vm-message-list))
- start)
- (save-restriction
- (widen)
- (vm-mail-internal (format "digest from %s" (buffer-name)))
- (use-local-map (copy-keymap (current-local-map)))
- (local-set-key "\C-c\C-y" 'vm-yank-message)
- (local-set-key "\C-cy" 'vm-yank-message-other-folder)
- (local-set-key "\C-c\C-s" 'vm-mail-send)
- (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
- (local-set-key "\C-c\C-v" vm-mode-map)
- (make-local-variable 'vm-forward-list)
- (setq vm-mail-buffer b
- vm-message-pointer mp
- vm-system-state 'forwarding
- vm-forward-list mlist
- default-directory dir)
- (goto-char (point-max))
- (setq start (point)
- mp mlist)
- (message "Building digest...")
- (while mp
- (insert-buffer-substring (marker-buffer (vm-start-of (car mp)))
- (vm-start-of (car mp))
- (vm-end-of (car mp)))
- (setq mp (cdr mp)))
- (vm-digestify-region start (point))
- (goto-char start)
- (setq mp mlist)
- (if prefix
- (progn
- (message "Building digest preamble...")
- (while mp
- (insert (vm-sprintf 'vm-digest-preamble-format (car mp)) "\n")
- (if vm-digest-center-preamble
- (progn
- (forward-char -1)
- (center-line)
- (forward-char 1)))
- (setq mp (cdr mp)))))
- (goto-char (point-min))
- (end-of-line)
- (message "Building digest... done"))))
-
- (defun vm-continue-composing-message (&optional not-picky)
- "Find and select the most recently used mail composition buffer.
- If the selected buffer is already a Mail mode buffer then it is
- buried before beginning the search. Non Mail mode buffers and
- unmodified Mail buffers are skipped. Prefix arg means unmodified
- Mail mode buffers are not skipped. If no suitable buffer is
- found, the current buffer remains selected."
- (interactive "P")
- (if (eq major-mode 'mail-mode)
- (bury-buffer (current-buffer)))
- (let ((b (vm-find-composition-buffer not-picky)))
- (if (not (or (null b) (eq b (current-buffer))))
- (switch-to-buffer b)
- (message "No composition buffers found"))))
-
- (defun vm-find-composition-buffer (&optional not-picky)
- (let ((b-list (buffer-list)) choice alternate)
- (save-excursion
- (while b-list
- (set-buffer (car b-list))
- (if (eq major-mode 'mail-mode)
- (if (buffer-modified-p)
- (setq choice (current-buffer)
- b-list nil)
- (and not-picky (null alternate)
- (setq alternate (current-buffer)))
- (setq b-list (cdr b-list)))
- (setq b-list (cdr b-list))))
- (or choice alternate))))
-
- (defun vm-mail-internal
- (&optional buffer-name to subject in-reply-to cc references newsgroups)
- (set-buffer (generate-new-buffer (or buffer-name "*VM-mail*")))
- (auto-save-mode auto-save-default)
- (mail-mode)
- (switch-to-buffer (current-buffer))
- (if (eq mail-aliases t)
- (progn
- (setq mail-aliases nil)
- (if (file-exists-p "~/.mailrc")
- (build-mail-aliases))))
- (if (stringp vm-mail-header-from)
- (insert "From: " vm-mail-header-from "\n"))
- (insert "To: " (or to "") "\n")
- (and cc (insert "Cc: " cc "\n"))
- (insert "Subject: " (or subject "") "\n")
- (and newsgroups (insert "Newsgroups: " newsgroups "\n"))
- (and in-reply-to (insert "In-Reply-To: " in-reply-to "\n"))
- (and references (insert "References: " references "\n"))
- (if mail-default-reply-to
- (insert "Reply-To: " mail-default-reply-to "\n"))
- (if mail-self-blind
- (insert "Bcc: " (user-login-name) "\n"))
- (if mail-archive-file-name
- (insert "FCC: " mail-archive-file-name "\n"))
- (insert mail-header-separator "\n")
- (save-excursion (vm-set-window-configuration 'composing-message))
- (if to
- (goto-char (point-max))
- (mail-position-on-field "To"))
- (run-hooks 'mail-setup-hook))
-
- (require 'mail-utils)
- (require 'sendmail)
-